
    //与disabled绑定器 用法差不多的其他布尔属性的绑定器
    "checked,readonly,selected".replace(rword, function(name) {
        bindingHandlers[name] = bindingHandlers.disabled
    })
    bindingHandlers.enabled = function(data, vmodels) {
        watchView(data.value, vmodels, data, function(val, elem) {
            elem.disabled = !val
        })
    }
    /////////////////////////// string preperty binding///////////////////////////
    //与href绑定器 用法差不多的其他字符串属性的绑定器
    //建议不要直接在src属性上修改，这样会发出无效的请求，请使用ms-src
    "title,alt,src,value,css,include".replace(rword, function(name) {
        bindingHandlers[name] = bindingHandlers.href
    })
    /////////////////////////// model binding  ///////////////////////////

    //将模型中的字段与input, textarea的value值关联在一起
    var modelBinding = bindingHandlers.model = function(data, vmodels) {
        var element = data.element
        var tagName = element.tagName
        if (typeof modelBinding[tagName] === "function") {
            var array = parseExpr(data.value, vmodels, data)
            if (array) {
                modelBinding[tagName](element, array[0], vmodels[0])
            }
        }
    }
    //如果一个input标签添加了model绑定。那么它对应的字段将与元素的value连结在一起
    //字段变，value就变；value变，字段也跟着变。默认是绑定input事件，
    modelBinding.INPUT = function(element, fn, scope) {
        if (element.name === void 0) {
            element.name = generateID()
        }
        var type = element.type,
                god = avalon(element)
        //当value变化时改变model的值
        var updateModel = function() {
            if (god.data("observe") !== false) {
                fn(scope, element.value)
            }
        }
        //当model变化时,它就会改变value的值
        var updateView = function() { //先执行updateView
            var neo = fn(scope)
            if (neo !== element.value) {
                element.value = neo
            }
        }
        if (/^(password|textarea|text)$/.test(type)) {
            var event = element.attributes["data-event"] || {}
            event = event.value
            if (event === "change") {
                avalon.bind(element, event, updateModel)
            } else {
                if (window.addEventListener) { //先执行W3C
                    element.addEventListener("input", updateModel, false)
                } else {
                    element.attachEvent("onpropertychange", updateModel)
                }
                if (DOC.documentMode >= 9) { //IE9 10
                    element.attachEvent("onkeydown", function(e) {
                        var key = e.keyCode
                        if (key === 8 || key === 46) {
                            updateModel() //处理回退与删除
                        }
                    })
                    element.attachEvent("oncut", updateModel) //处理粘贴
                }
            }
        } else if (type === "radio") {
            updateView = function() {
                element.checked = !!fn(scope)
            }
            updateModel = function() {
                if (god.data("observe") !== false) {
                    var val = !element.beforeChecked
                    fn(scope, val)
                    element.beforeChecked = element.checked = val
                }
            }

            function beforeChecked() {
                element.beforeChecked = element.checked
            }
            if (element.onbeforeactivate === null) {
                god.bind("beforeactivate", beforeChecked)
            } else {
                god.bind("mouseover", beforeChecked)
            }
            god.bind("click", updateModel)
        } else if (type === "checkbox") {
            updateModel = function() {
                if (god.data("observe") !== false) {
                    var method = element.checked ? "ensure" : "remove"
                    avalon.Array[method](fn(scope), element.value)
                }
            }
            updateView = function() {
                var array = [].concat(fn(scope)) //强制转换为数组
                element.checked = array.indexOf(element.value) >= 0
            }
            god.bind("click", updateModel) //IE6-8
        }
        Publish[expose] = updateView
        updateView.element = element
        updateView()
        delete Publish[expose]
    }
    modelBinding.SELECT = function(element, fn, scope, oldValue) {
        var god = avalon(element)

        function updateModel() {
            if (god.data("observe") !== false) {
                var neo = god.val()
                if (neo + "" !== oldValue) {
                    fn(scope, neo)
                    oldValue = neo + ""
                }
            }
        }

        function updateView() {
            var neo = fn(scope)
            if (neo + "" !== oldValue) {
                god.val(neo)
                oldValue = neo + ""
            }
        }
        god.bind("change", updateModel)
        Publish[expose] = updateView
        updateView.element = element
        updateView()
        delete Publish[expose]
    }
    modelBinding.TEXTAREA = modelBinding.INPUT
    //////////////////////////// 常用事件 binding  ////////////////////////
    "dblclick,mouseout,click,mouseover,mouseenter,mouseleave,mousemove,mousedown,mouseup,keypress,keydown,keyup,blur,focus,change".
            replace(rword, function(name) {
        bindingHandlers[name] = function(data) {
            data.args = [name]
            bindingHandlers.on.apply(0, arguments)
        }
    })
    if (!("onmouseenter" in root)) {
        var oldBind = avalon.bind
        var events = {
            mouseenter: "mouseover",
            mouseleave: "mouseout"
        }
        avalon.bind = function(elem, type, fn) {
            if (events[type]) {
                return oldBind(elem, events[type], function(e) {
                    var t = e.relatedTarget
                    if (!t || (t !== elem && !(elem.compareDocumentPosition(t) & 16))) {
                        delete e.type
                        e.type = type
                        return fn.call(elem, e)
                    }
                })
            } else {
                return oldBind(elem, type, fn)
            }
        }
    }
    